﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Script.Net.Scripts
{

	public class ScriptGenerator
	{

		public string Generate()
		{
			var depsServed = new List<string>();
			var items = ScriptFactory.Repository.GetScripts();
			var delayed = new List<IScriptItem>();
			string output = "";

			foreach (var item in items)
			{
				var indexes = new List<int>();

				for (int i = 0, len = delayed.Count; i < len; i++)
				{
					if (ProcessItem(delayed[i], depsServed, ref output))
					{
						if (!string.IsNullOrEmpty(delayed[i].Alias))
							depsServed.Add(delayed[i].Alias);
						indexes.Add(i);
					}
				}

				if (indexes.Count > 0)
					indexes.ForEach((i) => delayed.RemoveAt(i));

				var result = ProcessItem(item, depsServed, ref output);
				if (!result)
					delayed.Add(item);
				else
				{
					if (!string.IsNullOrEmpty(item.Alias))
						depsServed.Add(item.Alias);
				}
			}

			//If any leftover scripts, render them all
			if (delayed.Count > 0)
			{
				foreach (var item in delayed)
				{
					if (ProcessItem(item, null, ref output))
					{
						if (!string.IsNullOrEmpty(item.Alias))
						depsServed.Add(item.Alias);
					}
				}
			}

			return output;
		}

		private bool ProcessItem(IScriptItem item, List<string> depsServed, ref string output)
		{
			//If any dependencies not served
			if (depsServed != null && item.Dependencies != null && !item.Dependencies.All(i => depsServed.Contains(i)))
				return false;

			if (item is ScriptContent)
			{
				var cnt = (ScriptContent)item;
				output += "\r\n" + cnt.Content.ToHtmlString();
				return true;
			}
			else if (item is ScriptFile)
			{
				var file = (ScriptFile)item;
				output += "<script type='text/javascript' src='" + file.Path + "'></script>";
				return true;
			}

			return true;
		}

	}
}
